package org.zn.note.java8;

import java.util.function.Predicate;

/**
 * 策略模式
 * 定义一些算法(算法簇)，然后在运行时选择用哪个算法。
 * 1、代表算法的接口（策略接口）
 * 2、N个接口的具体实现
 * 3、使用该接口的客户
 * <p>
 * 用lombok改写：
 * 1、不用提前写好算法实现，在声明客户实例时，可以直接用lombok写算法
 * 2、甚至接口也可以用现成的，比如 {@link Predicate}
 */
public class Ch08_Pattern_Strategy {

    public static void main(String[] args) {
        // 在主流程里，将算法给到客户，决定客户的不同行为
        Validator numericValidator = new Validator(new IsNumeric());
        boolean b1 = numericValidator.validate("aaaa");
        Validator lowerCaseValidator = new Validator(new IsAllLowerCase());
        boolean b2 = lowerCaseValidator.validate("bbbb");
        System.out.printf("%s %s\n", b1, b2);

        // 如果用lombok改写
        Validator numericValidator2 =
                new Validator((String s) -> s.matches("[a-z]+"));
        boolean b3 = numericValidator2.validate("aaaa");
        Validator lowerCaseValidator2 =
                new Validator((String s) -> s.matches("\\d+"));
        boolean b4 = lowerCaseValidator2.validate("bbbb");
    }

    // 客户
    public static class Validator {
        private final ValidationStrategy strategy;

        public Validator(ValidationStrategy v) {
            this.strategy = v;
        }

        public boolean validate(String s) {
            return strategy.execute(s);
        }
    }

    // 接口
    public interface ValidationStrategy {
        boolean execute(String s);
    }

    // 实现1
    public static class IsAllLowerCase implements ValidationStrategy {
        public boolean execute(String s) {
            return s.matches("[a-z]+");
        }
    }

    // 实现2
    public static class IsNumeric implements ValidationStrategy {
        public boolean execute(String s) {
            return s.matches("\\d+");
        }
    }
}
